﻿using System;
using MakeItWeb.Framework;
using Telerik.Web.UI;
using System.Web.Security;
using System.Data;
using System.Web.UI.WebControls;
using System.Security.Permissions;
using System.Linq;
using System.Configuration;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Text;

namespace AllNations.WebAppAdmin
{
    public partial class SiteStructure : MakeItWebAdminPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            treeSiteStructure.ContextMenuItemClick += new Telerik.Web.UI.RadTreeViewContextMenuEventHandler(treeSiteStructure_ContextMenuItemClick);
            treeSiteStructure.NodeEdit += new RadTreeViewEditEventHandler(treeSiteStructure_NodeEdit);
            treeSiteStructure.NodeClick += new RadTreeViewEventHandler(treeSiteStructure_NodeClick);
            treeSiteStructure.PreRender += new EventHandler(treeSiteStructure_PreRender);
            btSaveNode.Click += new EventHandler(btSaveNode_Click);
            btAdd.Click += new EventHandler(btAdd_Click);
            btRemove.Click += new EventHandler(btRemove_Click);
            btRemoveAll.Click += new EventHandler(btRemoveAll_Click);

            if (!IsPostBack)
            {
                RefreshSiteStructure(false);
                ddAvailableRoles.DataSource = Roles.GetAllRoles();
                ddAvailableRoles.DataBind();
                ddAvailableRoles.Items.Insert(0, new ListItem("Everyone", string.Empty));
                var types = ConfigurationManager.GetSection("DynamicPageTypes") as NameValueCollection;
                if (types != null)
                    Array.ForEach(types.AllKeys, k => ddDynamicPageTypes.Items.Add(new ListItem(k)));
            }
        }

        void btRemoveAll_Click(object sender, EventArgs e)
        {
            foreach (ListItem item in lbAdminUsers.Items)
            {
                item.Selected = false;
                lbAvailableUsers.Items.Add(item);
            }
            lbAdminUsers.Items.Clear();
        }

        void btRemove_Click(object sender, EventArgs e)
        {
            List<string> lst = new List<string>();

            foreach (ListItem item in lbAdminUsers.Items)
            {
                if (item.Selected)
                    lst.Add(item.Value);
            }

            Array.ForEach(lst.ToArray(), i =>
            {
                var item = lbAdminUsers.Items.FindByValue(i);
                item.Selected = false;
                lbAdminUsers.Items.Remove(item);
                lbAvailableUsers.Items.Add(item);
            });
        }

        void btAdd_Click(object sender, EventArgs e)
        {
            List<string> lst = new List<string>();

            foreach (ListItem item in lbAvailableUsers.Items)
            {
                if (item.Selected)
                    lst.Add(item.Value);
            }

            Array.ForEach(lst.ToArray(), i =>
            {
                var item = lbAvailableUsers.Items.FindByValue(i);
                item.Selected = false;
                lbAvailableUsers.Items.Remove(item);
                lbAdminUsers.Items.Add(item);
            });
        }

        void treeSiteStructure_PreRender(object sender, EventArgs e)
        {
            treeSiteStructure.ContextMenus.Clear();
            foreach (RadTreeNode node in (sender as RadTreeView).GetAllNodes())
            {
                RadTreeViewContextMenu menu = new RadTreeViewContextMenu(); // node.Nodes.Count == 0 ? NodeMenu : NodeMenuWithChildren;
                menu.ID = string.Format("menu_{0}", node.Value.Replace("-", "_"));
                menu.Items.Add(new RadMenuItem() { Text = "Add child page", Value = "AddChild", ImageUrl = "~/Images/btn-plus.gif" });
                if (node.Nodes.Count == 0)
                    menu.Items.Add(new RadMenuItem() { Text = "Delete page", Value = "DeletePage", ImageUrl = "~/Images/delete.gif" });

                if (node.ParentNode != null && node.ParentNode.Nodes.Count > 1)
                {
                    if (node.Index > 0)
                        menu.Items.Add(new RadMenuItem() { Text = "Move up", Value = "MoveUp", ImageUrl = "~/Images/btn-arrow-up.gif" });

                    if (node.Index < node.ParentNode.Nodes.Count - 1)
                        menu.Items.Add(new RadMenuItem() { Text = "Move down", Value = "MoveDown", ImageUrl = "~/Images/btn-arrow-down.gif" });
                }
                treeSiteStructure.ContextMenus.Add(menu);
                node.ContextMenuID = menu.ID;
            }
        }

        void btSaveNode_Click(object sender, EventArgs e)
        {
            StoredProcArgs args = new StoredProcArgs();
            args["pNodeId"] = new Guid(treeSiteStructure.SelectedNode.Value);
            args["pNodeTitle"] = txtNodeTitle.Text.Trim();
            if (!string.IsNullOrEmpty(txtNodeUrl.Text.Trim()))
                args["pNodeUrl"] = txtNodeUrl.Text.Trim();
            if (!string.IsNullOrEmpty(txtNodeCd.Text.Trim()))
                args["pNodeCd"] = txtNodeCd.Text.Trim();
            if (!string.IsNullOrEmpty(txtNodeDescription.Text.Trim()))
                args["pNodeDescription"] = txtNodeDescription.Text.Trim();
            if (!string.IsNullOrEmpty(ddAvailableRoles.SelectedValue))
                args["pRole"] = ddAvailableRoles.SelectedValue;
            args["pUseGenericPageInd"] = cbUseGenericPageInd.Checked;
            if (cbUseGenericPageInd.Checked)
                args["pGenericPageType"] = ddDynamicPageTypes.SelectedValue;
            if (lbAdminUsers.Items.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                foreach (ListItem i in lbAdminUsers.Items)
                    sb.AppendFormat("{0},", i.Value);
                args["pAdminUsers"] = sb.ToString(0, sb.Length - 1);
            }
            GenericCud.ExecuteCud("proc_cm_SaveSiteMapNode", args);

            RadTreeNode selNode = treeSiteStructure.SelectedNode;

            RefreshSiteStructure(true);

            RadTreeNode newSelNode = treeSiteStructure.FindNodeByValue(selNode.Value);
            if (newSelNode != null)
                SelectNode(newSelNode);
        }

        void treeSiteStructure_NodeClick(object sender, RadTreeNodeEventArgs e)
        {
            RenderSelectedNodeSettings(e.Node);
        }

        void treeSiteStructure_NodeEdit(object sender, RadTreeNodeEditEventArgs e)
        {
            StoredProcArgs args = new StoredProcArgs();
            args["pNodeId"] = new Guid(e.Node.Value);
            args["pNodeTitle"] = e.Text;
            GenericCud.ExecuteCud("proc_cm_SaveSiteNodeTitle", args);

            RefreshSiteStructure(true);

            RadTreeNode node = treeSiteStructure.FindNodeByValue(e.Node.Value);
            if (node != null)
                SelectNode(node);
        }

        void treeSiteStructure_ContextMenuItemClick(object sender, Telerik.Web.UI.RadTreeViewContextMenuEventArgs e)
        {
            StoredProcArgs args = new StoredProcArgs();
            switch (e.MenuItem.Value)
            {
                case "AddChild":
                    Guid guidNewNodeId = Guid.NewGuid();
                    args["node_id"] = guidNewNodeId;
                    args["title"] = "New page";
                    args["parent_node_id"] = new Guid(e.Node.Value);
                    GenericCud.ExecuteCud("proc_cm_AddSiteMapNode", args);

                    RefreshSiteStructure(true);

                    RadTreeNode node = treeSiteStructure.FindNodeByValue(guidNewNodeId.ToString());
                    if (node != null)
                        SelectNode(node);
                    break;
                case "DeletePage":
                    args["pNodeId"] = new Guid(e.Node.Value);
                    GenericCud.ExecuteCud("proc_cm_DeleteSiteMapNode", args);

                    RadTreeNode parentNode = e.Node.ParentNode;

                    RefreshSiteStructure(true);

                    if (parentNode != null)
                    {
                        RadTreeNode pNode = treeSiteStructure.FindNodeByValue(parentNode.Value);
                        if (pNode != null)
                            SelectNode(pNode);
                    }
                    break;
                case "MoveUp":
                    SwapSiteMapOrder(e.Node, e.Node.ParentNode.Nodes[e.Node.Index - 1]);
                    break;
                case "MoveDown":
                    SwapSiteMapOrder(e.Node, e.Node.ParentNode.Nodes[e.Node.Index + 1]);
                    break;
            }
        }

        private void SwapSiteMapOrder(RadTreeNode radTreeNode, RadTreeNode radTreeNode_2)
        {
            StoredProcArgs args = new StoredProcArgs();
            args["pNodeId1"] = new Guid(radTreeNode.Value);
            args["pNodeId2"] = new Guid(radTreeNode_2.Value);

            GenericCud.ExecuteCud("proc_cm_SwapSiteNodeDisplayOrder", args);

            RefreshSiteStructure(true);

            RadTreeNode pNode = treeSiteStructure.FindNodeByValue(radTreeNode.Value);
            if (pNode != null)
                SelectNode(pNode);
        }

        private void RenderSelectedNodeSettings(RadTreeNode node)
        {
            StoredProcArgs args = new StoredProcArgs();
            args["pNodeId"] = new Guid(node.Value);
            using (DataSet ds = GenericQry.GetDataSet("proc_cm_GetSiteMapNode", args))
            {
                if (ds.Tables[0].Rows.Count == 0)
                    return;

                DataRow dr = ds.Tables[0].Rows[0];
                txtNodeTitle.Text = dr["node_title"].ToString();
                txtNodeUrl.Text = dr.IsNull("node_url") ? string.Empty : dr["node_url"].ToString();
                txtNodeCd.Text = dr.IsNull("node_cd") ? string.Empty : dr["node_cd"].ToString();
                txtNodeDescription.Text = dr.IsNull("node_description") ? string.Empty : dr["node_description"].ToString();
                ddAvailableRoles.SelectedValue = dr.IsNull("role") ? string.Empty : dr["role"].ToString();
                cbUseGenericPageInd.Checked = (bool)dr["use_generic_page_ind"];
                if (!dr.IsNull("generic_page_type"))
                {
                    var selItem = ddDynamicPageTypes.Items.FindByText((string)dr["generic_page_type"]);
                    ddDynamicPageTypes.SelectedValue = selItem.Value;
                }
                lbAdminUsers.Items.Clear();
                lbAvailableUsers.Items.Clear();

                var members = Membership.GetAllUsers();
                MembershipUser[] lstUsers = new MembershipUser[members.Count];
                members.CopyTo(lstUsers, 0);

                string[] aAdminUsers = dr.IsNull("admin_users") ? null : dr["admin_users"].ToString().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                var availableMembers = from m in lstUsers
                                       where aAdminUsers == null || !aAdminUsers.Contains(m.UserName)
                                       select m;

                lbAvailableUsers.DataSource = availableMembers;
                lbAvailableUsers.DataBind();

                lbAdminUsers.DataSource = aAdminUsers;
                lbAdminUsers.DataBind();
            }
        }

        private void RefreshSiteStructure(bool bRefreshSiteMap)
        {
            if (bRefreshSiteMap)
                Cache.Remove("SiteMapCache");

            treeSiteStructure.DataSource = GenericQry.GetDataSet("proc_cm_ListSiteMapNode", new StoredProcArgs());
            treeSiteStructure.DataBind();
            if (treeSiteStructure.Nodes.Count > 0)
                treeSiteStructure.Nodes[0].Expanded = true;
        }

        private void SelectNode(RadTreeNode node)
        {
            node.Selected = true;
            node.ExpandParentNodes();
            RenderSelectedNodeSettings(node);
        }
    }
}